/////////////////////////////////////////
///file: jud_cmd_128
///Author: Dp
///////////////////////////////////////////////

module jud_cmd_128 (//input
	clk_1m,
	rst_n,
	oe_128,//等效成上层给的req
	frame_vaild,
	sram_ack,
	dll_data,
	crc_from_dll,
	p_err,
	sram_data_out,
	//output
	sram_wr,
	sram_rd,
	sram_addr,
	jud_err,
	crc_req,
	end_flag
);
input clk_1m,rst_n,oe_128,frame_vaild,sram_ack;
input [7:0] dll_data;
input [15:0]crc_from_dll;
input p_err;
input [7:0]sram_data_out;

output sram_wr,sram_rd;
output [12:0]sram_addr;
output jud_err;
output crc_req;
output end_flag;


reg [7:0] uid_data;//存入dll来的数据的reg
reg 	jud_err_reg;//判断芯片是否为好的标志位
reg 	sram_wr_reg;//sram write control signal
reg 	sram_rd_reg;//sram read control signal
reg [12:0]sram_addr_reg;
reg [3:0] state;
reg [3:0] nstate;
reg crc_req_r;
//reg flag;
reg [7:0]sram_rd_data;
reg end_flag_r;
wire	stNINE;
wire    stDone;
		
parameter uidg00_addr128 = 13'd4;//需要后来设置
parameter   IDLE = 4'b0,    ONE = 4'd1,  TWO = 4'd2,    THREE = 4'd3, 
		    FOUR = 4'd4,   FIVE = 4'd5,  SIX = 4'd6,    SEVEN = 4'd7,   
		   EIGHT = 4'd8,   NINE = 4'd9,  TEN = 4'd10,  ELEVEN = 4'd11, 
		  TWELVE =4'd12,   DONE = 4'd13;		
		
		
		///********output assign**********/////////
//assign  jud_err = (^jud_err_reg && (state == DONE));//第一片打码的晶圆检测128位数据是否为好的	
assign  jud_err     =  jud_err_reg;	
assign  end_flag	=  end_flag_r;				
assign	sram_addr	=	oe_128	?	sram_addr_reg	:13'h0000;
assign	sram_rd		=	oe_128	?	sram_rd_reg	:	1'b0;
assign	sram_wr		=	oe_128	?	sram_wr_reg	:	1'b0;	
assign  crc_req     =   oe_128 && (state < 4'd10);
assign  stNINE      =   state == NINE;
//assign  stAFNINE    =   state > NINE;
assign 	stDone = state == DONE;
	/****************state machine**********************/
always @(posedge clk_1m or negedge rst_n)
    if(rst_n == 1'b0)
	   state <= IDLE;
	else if(oe_128 == 1'b0)
	   state <= IDLE;
	else
	   state <= nstate;

always @(*)
if(rst_n ==	1'b0)
		nstate = IDLE;
else if(oe_128	==	1'b0)
	    nstate = IDLE;
else	
	case(state)
		IDLE     : nstate = (~oe_128)?IDLE:(frame_vaild?ONE:IDLE);	
		ONE      : nstate = (~oe_128)?IDLE:(frame_vaild?TWO:ONE);
		TWO      : nstate = (~oe_128)?IDLE:(frame_vaild?THREE:TWO);
		THREE    : nstate = (~oe_128)?IDLE:(frame_vaild?FOUR:THREE);
		FOUR     : nstate = (~oe_128)?IDLE:(frame_vaild?FIVE:FOUR);	
		FIVE     : nstate = (~oe_128)?IDLE:(frame_vaild?SIX:FIVE);
		SIX      : nstate = (~oe_128)?IDLE:(frame_vaild?SEVEN:SIX);		
		SEVEN    : nstate = (~oe_128)?IDLE:(frame_vaild?EIGHT:SEVEN);
		EIGHT    : nstate = (~oe_128)?IDLE:(frame_vaild?NINE:EIGHT);
		NINE     : nstate = (~oe_128)?IDLE:(frame_vaild?TEN:NINE);
		TEN      : nstate = (~oe_128)?IDLE:(frame_vaild?ELEVEN:TEN);
		ELEVEN   : nstate = (~oe_128)?IDLE:(frame_vaild?TWELVE:ELEVEN);
		TWELVE   : nstate = (~oe_128)?IDLE:(frame_vaild?DONE:TWELVE);
		DONE     : nstate = (~oe_128)?IDLE:(DONE);
		default  : nstate = IDLE;
	endcase

			
always@(posedge	clk_1m or negedge rst_n)
	if(~rst_n)begin
		sram_addr_reg	<=	13'd0;
		sram_rd_reg		<=	1'b0;
		sram_wr_reg		<=	1'b0;
		uid_data        <=  8'h00;
	end
	else if(~oe_128)begin
		sram_addr_reg	<=	13'd0;
		sram_rd_reg		<=	1'b0;
		sram_wr_reg		<=	1'b0;
		uid_data        <=  8'h00;
	end
	else 
	case(state)
	IDLE:begin
		sram_addr_reg	<=	13'd0;
		sram_rd_reg	    <=  1'b0;
		sram_wr_reg	    <=  1'b0;
		uid_data        <=  8'h00;
	end
	ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT:
	begin
		sram_addr_reg	<=	13'd0;
		sram_rd_reg	    <=  1'b0;
		sram_wr_reg	    <=  1'b0;
		uid_data        <=  8'h00;
	end
	NINE:
	begin
		sram_addr_reg  <=  uidg00_addr128;//将要读的数据的地址存入地址寄存器中
	end
	TEN,ELEVEN,TWELVE: 
	begin
		if(!p_err && frame_vaild)
		begin
			sram_rd_reg	   <=  1'b1;		
		end
		if(sram_ack)
		begin
			sram_rd_reg	   <=  1'b0;
			sram_addr_reg  <= sram_addr_reg + 1'b1; 
		end	
	end
	default: begin
				sram_addr_reg	<=	13'd0;
				sram_rd_reg	    <=  1'b0;
				sram_wr_reg	    <=  1'b0;
				uid_data        <=  8'h00;
	end
	endcase

always@(posedge clk_1m or negedge rst_n)
	if(~rst_n)
	  end_flag_r <= 1'b0;
	else if(state == DONE) 
			end_flag_r <= 1'b1;
		else
			end_flag_r <= 1'b0;
			
	  
	
	
always @(posedge clk_1m or negedge rst_n)
	if(~rst_n)
		jud_err_reg <= 1'b0;
	else if(~oe_128)
		jud_err_reg <= 1'b0;
	else if (stDone)
		jud_err_reg <= jud_err_reg;
	else if(stNINE & frame_vaild)
		jud_err_reg <= (jud_err_reg | p_err) || (crc_from_dll != 16'd0);
	else if(frame_vaild)
		jud_err_reg <= jud_err_reg | p_err;
	else if(sram_ack)
		jud_err_reg <= jud_err_reg || (uid_data != sram_data_out);




		
endmodule 		
			
			
			
			
	
	
